{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "'''\n",
    "【课程4.1】  字典dict基本概念\n",
    "\n",
    "字典是另一种可变容器模型，且可存储任意类型对象。\n",
    "字典的每个键值(key=>value)对用冒号(:)分割，每个对之间用逗号(,)分割，整个字典包括在花括号({})中 \n",
    "\n",
    "键必须是唯一的，但值则不必。\n",
    "\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'大头儿子': 6, '隔壁老王': 37, '小头爸爸': 35} <class 'dict'>\n",
      "[{'name': 'Tom', 'age': 18}, {'name': 'Jack', 'age': 19}, {'name': 'Alex', 'age': 17}]\n"
     ]
    }
   ],
   "source": [
    "# 什么是映射？什么是字典dict？\n",
    "\n",
    "name = ['大头儿子','小头爸爸','隔壁老王']\n",
    "age = [6,35,37]\n",
    "# 首先虽然序列是有顺序的，但还是不能直接把名字和年龄关联起来，这里只是顺序对上，且并没有一对一的关系\n",
    "\n",
    "dic = {'大头儿子':6, '小头爸爸': 35, '隔壁老王':37}\n",
    "print(dic,type(dic))\n",
    "# 用{}来表示，按照key：value来表示字典中的元素，其中key是键，value是值，key-value也就是键值对\n",
    "# 这里dic就是一个字典类型的变量\n",
    "\n",
    "dic = [{'name':'Tom', 'age':18},{'name':'Jack', 'age':19},{'name':'Alex', \"age\":17}]\n",
    "print(dic)\n",
    "# 一个以字典为元素的列表，有没有觉得键值对很像数据中的字段和字段值？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a': 2}\n",
      "{'var4': {'b': 2, 'a': 1}, 'var2': 'hello', 'var3': [1, 2, 3], 'var1': 1}\n",
      "{'var4': '任意修改其中一个值', 'var2': 'hello', 'var5': '添加一个值', 'var3': [1, 2, 3]}\n",
      "{}\n"
     ]
    }
   ],
   "source": [
    "# 字典的特点\n",
    "\n",
    "dic = {'a':1,'b':2,'c':3}\n",
    "# 键值对，一定共同出现，不能只有一个\n",
    "\n",
    "dic = {'a':1,'a':2}\n",
    "print(dic)\n",
    "# 不允许同一个键出现两次：创建时如果同一个键被赋值两次，后一个值会被记住\n",
    "\n",
    "dic = {'var1':1, 'var2':'hello', 'var3':[1,2,3], 'var4':{'a':1,'b':2}}\n",
    "# key必须是字符串，value则可以是任意对象：数值，字符串，序列，字典\n",
    "\n",
    "print(dic)\n",
    "# 字典是一个无序集合,序列由于没有key来做对应，所以以顺序来对应值\n",
    "# 序列有顺序，字典没有！\n",
    "\n",
    "dic['var5'] = '添加一个值'  # 任意添加元素\n",
    "dic['var4'] = '任意修改其中一个值'  # 任意修改元素\n",
    "del dic['var1']  # 任意删除元素\n",
    "print(dic)\n",
    "\n",
    "dic.clear()  # 清空词典所有条目\n",
    "print(dic)\n",
    "\n",
    "del dic  # 删除词典\n",
    "#print(dic)  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'n': 'aa', 'm': 10, 'h': [1, 2, 3]}\n",
      "{'b': 'ggg', 'a': 'fff'} {'d': 2, 'c': 1} {'f': [3, 4], 'e': [1, 2]}\n",
      "{'b': None, 'a': None, 'c': None} {'b': 'hello', 'a': 'hello', 'c': 'hello'}\n"
     ]
    }
   ],
   "source": [
    "# 申明一个字典\n",
    "\n",
    "dic = {'a':1,'b':2}\n",
    "# 最简单直接的方式，手动书写申明一个字典变量，注意是：不是=\n",
    "\n",
    "dic = dict(m = 10 ,n = 'aa', h = [1,2,3])\n",
    "print(dic)\n",
    "# dict()函数\n",
    "\n",
    "lst1=[(\"a\",\"fff\"),(\"b\",\"ggg\")]\n",
    "lst2=[[\"c\",1],[\"d\",2]]\n",
    "lst3=((\"e\",[1,2]),(\"f\",[3,4]))\n",
    "dic1 = dict(lst1)\n",
    "dic2 = dict(lst2)\n",
    "dic3 = dict(lst3)\n",
    "print(dic1,dic2,dic3)\n",
    "# dict()由序列生成一个字典，嵌套序列，可以是list或者tuple\n",
    "\n",
    "keys = [\"a\", \"b\", \"c\"]\n",
    "dic1 = dict.fromkeys(keys)\n",
    "dic2 = dict.fromkeys(keys, 'hello')\n",
    "print(dic1,dic2)\n",
    "# 只有key，直接生成一个字典"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "小作业\n",
    "\n",
    "① 用dict函数的时候，和直接申明一个字典，操作上什么区别？\n",
    "\n",
    "② 用dict()函数从序列创建字典的时候，对序列有要求吗？必须是列表吗？\n",
    "\n",
    "③ 字典是无序的，强化一下\n",
    "\n",
    "④ 以dict()函数生成一个人的成绩单，包括语文，数学，外语，物理，化学几个元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "'''\n",
    "【课程4.2】  字典常用操作\n",
    "\n",
    "字典内置函数&方法\n",
    "\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'b': 2, 'd': 4, 'a': 1, 'c': 3} {'d': 4, 'c': 3}\n",
      "{'n': 2, 'm': 1, 'p': 3, 'q': 4} {'n': 2, 'm': 1, 'p': 3, 'q': 4}\n",
      "{'n': 2, 'm': 1, 'p': 3, 'q': 4} {'n': 2, 'm': 1, 'p': 3}\n",
      "4\n",
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "# 字典常用操作\n",
    "\n",
    "dic1 = {\"a\":1, \"b\":2}\n",
    "dic2 = {\"c\":3, \"d\":4}\n",
    "dic1.update(dic2)\n",
    "print(dic1,dic2)\n",
    "# dict.update()方法：更新/合并一个字典，把第二个字典合并到第一个字典，改变了第一个字典\n",
    "\n",
    "a = {'m':1 , 'n':2 , 'p':3}\n",
    "b = a\n",
    "a.update({'q':4})\n",
    "print(a,b)\n",
    "# 和序列的原理一样，a和b指向同一个字典，所以会一起更新\n",
    "\n",
    "a = {'m':1 , 'n':2 , 'p':3}\n",
    "b = a.copy()\n",
    "a.update({'q':4})\n",
    "print(a,b)\n",
    "# 通过.copy()方法，复制一个新的字典\n",
    "\n",
    "print(len(a))\n",
    "# 查看字典元素个数\n",
    "\n",
    "print('m' in a)\n",
    "print(1 in a)\n",
    "# in / not in ：判断是否包含，这里的判断对象是key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "'''\n",
    "【课程4.3】  字典的元素访问及遍历\n",
    "\n",
    "如何读取字典？\n",
    "\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "somewhere\n",
      "shop\n",
      "nothing\n",
      "None\n",
      "dict_keys(['information', 'name', 'city']) <class 'dict_keys'>\n",
      "['information', 'name', 'city']\n",
      "dict_values([{'num': 66663333, 'address': 'somewhere'}, 'shop', 'shanghai']) <class 'dict_values'>\n",
      "[{'num': 66663333, 'address': 'somewhere'}, 'shop', 'shanghai']\n",
      "dict_items([('information', {'num': 66663333, 'address': 'somewhere'}), ('name', 'shop'), ('city', 'shanghai')]) <class 'dict_items'>\n",
      "[('information', {'num': 66663333, 'address': 'somewhere'}), ('name', 'shop'), ('city', 'shanghai')]\n"
     ]
    }
   ],
   "source": [
    "# 字典的元素访问\n",
    "\n",
    "dic = {'a':1, \"b\":2, \"c\":3}\n",
    "print(dic['a'])\n",
    "#print(dic[1])  # 不能用序列的索引方式\n",
    "# 字典里面也就同样的意思，但字典没有顺序，以key来作为指向，所以指向的key必须存在\n",
    "\n",
    "poi = {'name':'shop', 'city':'shanghai', 'information':{'address':'somewhere', 'num':66663333}}\n",
    "print(poi['information']['address'])\n",
    "# 对于嵌套字典，输出嵌套内容，通过重复指向来输出\n",
    "\n",
    "print(poi.get('name'))\n",
    "print(poi.get('type',print('nothing')))\n",
    "# .get(key)方法：直接查看key的value，如果没有相应key则返回None，添加print参数可以多返回一个值\n",
    "\n",
    "print(poi.keys(),type(poi.keys()))\n",
    "print(list(poi.keys()))\n",
    "# .keys()方法：输出字典所有key，注意这里的输出内容格式是视图，可以用list()得到key的列表，类似range()\n",
    "\n",
    "print(poi.values(),type(poi.values()))\n",
    "print(list(poi.values()))\n",
    "# .values()方法：输出字典所有values，原理同.keys()方法\n",
    "\n",
    "print(poi.items(),type(poi.items()))\n",
    "print(list(poi.items()))\n",
    "# .items()方法：输出字典所有items（元素），原理同.keys()方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "information\n",
      "name\n",
      "city\n",
      "-------\n",
      "{'num': 66663333, 'address': 'somewhere'}\n",
      "shop\n",
      "shanghai\n",
      "-------\n",
      "key为 information, value为 {'num': 66663333, 'address': 'somewhere'}\n",
      "key为 name, value为 shop\n",
      "key为 city, value为 shanghai\n",
      "-------\n"
     ]
    }
   ],
   "source": [
    "# 字典的元素遍历\n",
    "\n",
    "poi = {'name':'shop', 'city':'shanghai', 'information':{'address':'somewhere', 'num':66663333}}\n",
    "for key in poi.keys():\n",
    "    print(key)\n",
    "print('-------')\n",
    "\n",
    "for value in poi.values():\n",
    "    print(value)\n",
    "print('-------')\n",
    "\n",
    "for (k,v) in poi.items():\n",
    "    print('key为 %s, value为 %s' %(k,v))\n",
    "print('-------')  \n",
    "# for函数遍历"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "小作业\n",
    "\n",
    "① dict.keys()生成的是不是列表？\n",
    "\n",
    "② 如何判断一个value是否存在于字典中？"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
